package com.yunkeji.api.call.controller;

import com.yunkeji.api.auth.vo.ToLoginVo;
import com.yunkeji.api.call.bo.*;
import com.yunkeji.api.call.service.CallService;
import com.yunkeji.api.call.vo.*;
import com.yunkeji.api.user.service.AppUserInfoService;
import com.yunkeji.common.annotation.RepeatSubmit;
import com.yunkeji.common.core.controller.BaseController;
import com.yunkeji.common.core.domain.R;
import com.yunkeji.common.enums.app.AccountTypeEnums;
import com.yunkeji.common.helper.LoginHelper;
import com.yunkeji.config.annotation.ApiAuth;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.concurrent.TimeUnit;

/**
 * <预付费,退返逻辑> 备注... 1. startAnswer调用后会扣除第一分钟的余额,并开始计时70秒,70秒内未收到两次心跳,调用startCancel 2. duration =
 * startCancel的调用时间 - startAnswer的调用时间 3. price_times = 心跳计费次数
 *
 * <p>0.正常情况,主叫或者被叫挂电话 (duration/60) = price_times 计费正常 (duration/60) < price_times 实际通话时间小于计费次数
 * 执行退费 仅退一分钟 (duration/60) > price_times 实际通话时间大于计费次数 执行扣费 有多少扣多少
 *
 * <p>1.主叫不报心跳/被叫不报心跳/主叫被叫都不报心跳/主叫断网/被叫断网/主叫被叫同时断网
 *
 * <p>执行70秒未收到心跳逻辑,此时只有一种情况 (duration/60) > price_times 实际通话时间大于计费次数 执行扣费 有多少扣多少
 *
 * @author 老张
 */

/**
 * 音视频呼叫
 *
 * @author 老张
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/v1/call")
public class CallController extends BaseController {
    private final CallService callService;
    private final AppUserInfoService appUserInfoService;

    /**
     * 查询主叫或者被叫的信息 sendHelloList
     *
     * @author 老张
     */
    @PostMapping("/queryUser")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    public R<ToLoginVo> queryUser(@Valid @RequestBody QueryUserBo baseId) {
        return R.ok(appUserInfoService.getUserInfoByPlatformId(baseId.getPlatformId()));
    }

    /**
     * 1.主叫发起通话
     *
     * @author 老张
     */
    @PostMapping("/startCall")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    public R<CallSheetVo> startCall(@Valid @RequestBody StartCallBo startCallBo) {
        startCallBo.setCallUid(LoginHelper.getUserId());
        return R.ok(callService.startCall(startCallBo));
    }

    /**
     * 2.被叫振铃
     *
     * @author 老张
     */
    @PostMapping("/startRinging")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    public R recCall(@Valid @RequestBody CallProcessBo bo) {
        callService.startRinging(bo);
        return R.ok();
    }

    /**
     * 3.被叫接听-创建聊天房间-返回userSig
     *
     * @author 老张
     */
    @PostMapping("/startAnswer")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    public R<StartAnswerVo> startAnswer(@Valid @RequestBody StartAnswerBo bo) {
        return R.ok(callService.startAnswer(bo));
    }

    /**
     * 4.主叫确认
     *
     * @author 老张
     */
    @PostMapping("/startConfirm")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    public R<StartConfirm> startConfirm(@Valid @RequestBody CallProcessBo bo) {
        return R.ok(callService.startConfirm(bo));
    }

    /**
     * 4.主叫/被叫挂断电话
     *
     * @author 老张
     */
    @PostMapping("/startCancel")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    @RepeatSubmit(interval = 3, timeUnit = TimeUnit.SECONDS, message = "操作过快,三秒后再试")
    public R<StartCancel> startCancel(@Valid @RequestBody StartCancelBo bo) {
        bo.setBillUid(LoginHelper.getUserId());
        return R.ok(callService.startCancel(bo));
    }

    /**
     * 5.通话计费-通话保持
     *
     * @author 老张
     */
    @PostMapping("/startBill")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    public R<StartBill> startBill(@Valid @RequestBody StartBillBo bo) {
        bo.setBillUid(LoginHelper.getUserId());
        StartBill restMinute = callService.startBill(bo);
        restMinute.setTraceInf("计费溯源信息:" + bo.getUcid());
        return R.ok(restMinute);
    }

    /**
     * 6.通话评分
     *
     * @author 老张
     */
    @PostMapping("/startScore")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    @RepeatSubmit(interval = 3, timeUnit = TimeUnit.SECONDS, message = "操作过快,三秒后再试")
    public R callScore(@Valid @RequestBody StartScoreBo bo) {
        callService.startScore(bo);
        return R.ok();
    }

    /**
     * 7.通话质检
     *
     * @author 老张
     */
    @PostMapping("/startCheck")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    @RepeatSubmit(interval = 10, timeUnit = TimeUnit.SECONDS, message = "操作过快,三秒后再试")
    public R<CheckVo> startCheck(@Valid @RequestBody StartCheck bo) {
        return R.ok(callService.startCheck(bo));
    }

    /**
     * 8.加入房间
     *
     * @author 老张
     */
    @PostMapping("/startJoin")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    public R<StartJoinVo> startJoin(@RequestBody @Valid StartJoinBo startJoinBo) {
        return R.ok(callService.startJoin(startJoinBo));
    }

    /**
     * 开屏后 检查是否有正在通话的话单
     *
     * @author 老张
     */
    @PostMapping("/queryCallSheet")
    @ApiAuth(allow = {AccountTypeEnums.客服, AccountTypeEnums.用户})
    public R<QueryCallSheetVo> queryCallSheet() {
        return R.ok(callService.queryCallSheet());
    }
}
